﻿using DotXxlJob.Core;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using System.Text.RegularExpressions;
using XYS.Core.Models;

namespace XYS.Service.Core.Middlewares
{
    /// <summary>
    /// XxlJobExecutorMiddleware
    /// </summary>
    public class XxlJobExecutorMiddleware
    {
        private readonly IServiceProvider _provider;
        private readonly RequestDelegate _next;

        private readonly XxlRestfulServiceHandler xxlRestfulServiceHandler;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="provider"></param>
        /// <param name="next"></param>
        public XxlJobExecutorMiddleware(IServiceProvider provider, RequestDelegate next)
        {
            this._provider = provider;
            this._next = next;
            this.xxlRestfulServiceHandler = _provider.GetService<XxlRestfulServiceHandler>();
        }

        List<string> pathWhitelist = new List<string>()
        {
            "/beat",
            "/idlebeat",
            "/run",
            "/kill",
            "/log"
        };

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task Invoke(HttpContext context)
        {
            if (GlobalCoreSetting.FormatRequestsIgnore.Any(x => Regex.IsMatch(context.Request.Path.Value, "^" + Regex.Escape(x).Replace("\\*", ".*") + "$")))
            { await _next.Invoke(context); return; }

            if (xxlRestfulServiceHandler == null) { await _next.Invoke(context); return; }

            if (string.IsNullOrEmpty(context.Request.ContentType)) { await _next.Invoke(context); return; }
            string contentType = context.Request.ContentType;

            if ("POST".Equals(context.Request.Method, StringComparison.OrdinalIgnoreCase)
                && contentType.ToLower().StartsWith("application/json")
                && context.Request.Path != null
                && pathWhitelist.Contains(context.Request.Path.ToString().ToLower()))
            {
                await xxlRestfulServiceHandler.HandlerAsync(context.Request, context.Response);
                return;
            }
            await _next.Invoke(context);
        }
    }
}
